<?php
namespace App\Models\System;

use App\Exceptions\ApiException;
use App\Providers\LengthAwarePaginatorProvider;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Enums\System\SysDictData\{IsDefault, Status};

/**
* 字典数据表 模型
* @create 2023-08-21 22:05:25
*/
class SysDictDataModel extends \App\Models\BaseModel {
    use HasFactory;


    const Table         = "sys_dict_data";
    const PrimaryKey    = "dict_code";
    public $timestamps  = true;


    static $Wheres = ['dict_code', 'dict_type', 'status'];     // 直接定义column, 默认where(column, '=', value)
    public function __construct($attributes = []) {
        parent::__construct($attributes);

        // static::$Wheres['dict_code'] = fn($q, $v) => $q->where(atn('dict_code'), '=', $v);
        static::$Wheres['dict_label']   = fn($q, $v) => $q->where(atn('dict_label'), 'like', "%{$v}%");
    }


    /** ========== 常用查询 ========== */
    static $Vo  = ['dict_code','dict_sort','dict_label','dict_value','dict_type','css_class','list_class','is_default','status','create_by','create_time','remark',];
    static $Voi = ['*', ];


    /**
     * 根据条件分页查询字典数据
     * 
     * @param $dictData 字典数据信息
     * @return SysDictDataModel[]|Collection 字典数据集合信息
     */
    public function selectDictDataList(array $dictData): Collection {
        return $this->selectVo()
            ->wheres($dictData, 'dict_code', 'dict_type', 'dict_label', 'status')
            ->orderBy('dict_sort')
            ->get()
            ;
    }

    /**
     * 根据字典类型查询字典数据
     * 
     * @param string dictType 字典类型
     * @return SysDictDataModel[]|Collection 字典数据集合信息
     */
    public function selectDictDataByType(string $dictType): Collection {
        return $this->selectVo()
            ->where('status', '=', '0')
            ->where('dict_type', '=', $dictType)
            ->orderBy('dict_sort')
            ->get()
            ;
    }

    /**
     * 根据字典类型和字典键值查询字典数据信息
     * 
     * @param $dictType 字典类型
     * @param $dictValue 字典键值
     * @return string 字典标签
     */
    public function selectDictLabel(string $dictType, string $dictValue): string {
        return throw_str(
            $this->select('dict_label')
                ->where('dict_type', '=', $dictType)
                ->where('dict_value', '=', $dictValue)
                ->first()['dict_lable']
            ?? "字典数据({$dictType}-$dictValue)查找失败"
        );
    }

    /**
     * 根据字典数据ID查询信息
     * 
     * @param $dictCode 字典数据ID
     * @return SysDictDataModel 字典数据
     */
    public function selectDictDataById(int $dictCode): SysDictDataModel {
        return throw_str(
            $this->selectVo()
                ->where('dict_code', '=', $dictCode)
                ->first() 
            ?? "字典数据({$dictCode})查找失败"
        );
    }

    /**
     * 查询字典数据
     * 
     * @param $dictType 字典类型
     * @return int 字典数据
     */
    public function countDictDataByType(string $dictType): int {
        return $this
                ->select(static::PrimaryKey)
                ->where('dict_type', '=', $dictType)
                ->count()
                ;
    }

    /**
     * 通过字典ID删除字典数据信息
     * 
     * @param $dictCode 字典数据ID
     * @return int 结果
     */
    public function deleteDictDataById(int $dictCode): int {
        return $this->deleteDictDataByIds([$dictCode]);
    }

    /**
     * 批量删除字典数据信息
     * 
     * @param $dictCodes 需要删除的字典数据ID
     * @return int 结果
     */
    public function deleteDictDataByIds(array $dictCodes): int {
        return $this
            ->whereIn('dict_code', $dictCodes)
            ->delete()
            ;
    }

    /**
     * 新增字典数据信息
     * 
     * @param $dictData 字典数据信息
     * @return SysDictDataModel 结果
     */
    public function insertDictData(array $dictData): SysDictDataModel {
        $values = static::when(
                    $dictData,
                    'dict_sort',
                    'dict_label',
                    'dict_value',
                    'dict_type',
                    'css_class',
                    'list_class',
                    'is_default',
                    'status',
                    'remark',
                    'create_by',
                );
        return throw_str(
            static::row_add($values)
        );
    }

    /**
     * 修改字典数据信息
     * 
     * @param $dictData 字典数据信息
     * @return int 结果
     */
    public function updateDictData(array $dictData): int {
        $values = static::when(
                    $dictData,
                    'dict_sort',
                    'dict_label',
                    'dict_value',
                    'dict_type',
                    'css_class',
                    'list_class',
                    'is_default',
                    'status',
                    'remark',
                    'update_by',
                );
        return $this
            ->where(atn('dict_code'), '=', get_value($dictData, 'dict_code'))
            ->update($values)
            ;
    }

    /**
     * 同步修改字典类型
     * 
     * @param $oldDictType 旧字典类型
     * @param $newDictType 新旧字典类型
     * @return int 结果
     */
    public function updateDictDataType(string $oldDictType, string $newDictType): int {
        return $this
            ->where('dict_type', '=', $oldDictType)
            ->update(['dict_type'=>$newDictType])
            ;
    }

    /** 根据DictCode获取 */
    public function selectByDictCode($dict_code): SysDictDataModel {
        $where = [['dict_code', '=', "{$dict_code}"]];
        return throw_str(
            static::row($where) ?? "数据($dict_code)为空~"
        );
    }


    /** 获取列表 @return SysDictData[]+paginator() */
    public function selectList(int|array $pag=1, array $param=[]): LengthAwarePaginatorProvider {
        return static::rows_pag($pag, [], fn($q)=>$q
                    // ->when(isset($param['dict_code']), fn($q)=>$q->where('dict_code', '=', $param['dict_code']))
                    ->wheres($param, 'dict_code','is_default','status')
                    ->orderByDesc("dict_code")
        );
    }


    /** 插入数据 */
    public function insertData(array $data): SysDictDataModel {
        return throw_str(
            static::row_add([
                // 'dict_code'      => $data['dict_code'],
                'dict_sort'         => $data['dict_sort'] ?? '0',
                'dict_label'        => $data['dict_label'] ?? '',
                'dict_value'        => $data['dict_value'] ?? '',
                'dict_type'         => $data['dict_type'] ?? '',
                'css_class'         => $data['css_class'] ?? '',
                'list_class'        => $data['list_class'] ?? '',
                'is_default'        => $data['is_default'] ?? 'N',
                'status'            => $data['status'] ?? '0',
                'create_by'         => $data['create_by'] ?? '',
                // 'create_time'    => $data['create_time'] ?? '',
                'update_by'         => $data['update_by'] ?? '',
                // 'update_time'    => $data['update_time'] ?? '',
                'remark'            => $data['remark'] ?? '',
            ])
        );
    }


    /** 更新数据 */
    public function updateData(int|array $idOrWhere, array $data): SysDictDataModel {
        $values = static::when(
                    $data, 
                    // 'dict_code',
                    'dict_sort',
                    'dict_label',
                    'dict_value',
                    'dict_type',
                    'css_class',
                    'list_class',
                    'is_default',
                    'status',
                    'create_by',
                    // 'create_time',
                    'update_by',
                    // 'update_time',
                    'remark',
                );
        return throw_str(
            static::row_update($idOrWhere, $values)
        );
    }


    /** 删除数据 */
    public function deleteData(int|array $idOrWhere): SysDictDataModel {
        return throw_str(
            static::row_delete($idOrWhere)
        );
    }




}